package com.tungse.niostudy.d1;

import java.io.IOException;
import java.net.InetSocketAddress;
import java.nio.ByteBuffer;
import java.nio.channels.ClosedChannelException;
import java.nio.channels.SelectionKey;
import java.nio.channels.Selector;
import java.nio.channels.ServerSocketChannel;
import java.nio.channels.SocketChannel;
import java.util.Iterator;

/**
 * @Author : Tungse
 * @Date: 2025/7/5 9:01
 * @Description:
 */
public class NoiServer {
    public static void main(String[] args) throws IOException {
        Selector selector = Selector.open();

        ServerSocketChannel ssc = ServerSocketChannel.open();
        ssc.configureBlocking(false);//设置非阻塞
        ssc.bind(new InetSocketAddress(9999));
        ssc.register(selector, SelectionKey.OP_ACCEPT);//注册到选择器，并指定监听事件

        while (true) {
            selector.select();
            Iterator<SelectionKey> iterator = selector.selectedKeys().iterator();
//            Set<SelectionKey> selectionKeys = iterator;
            while (iterator.hasNext()) {
                SelectionKey key = iterator.next();
                iterator.remove();

                if (key.isAcceptable()) {
                    handleAccept(ssc, selector);
                } else if (key.isReadable()) {
                    handleRead(key); // 修改后的读取处理
                }
            }
        }
    }
    private static void handleAccept(ServerSocketChannel ssc, Selector selector) throws IOException {
        SocketChannel clientChannel = ssc.accept();
        clientChannel.configureBlocking(false);
        clientChannel.register(selector, SelectionKey.OP_READ);
        System.out.println("客户端已连接" + clientChannel.getRemoteAddress());
    }

    private static void handleRead(SelectionKey key) {
        SocketChannel channel = (SocketChannel) key.channel();
        ByteBuffer buffer = ByteBuffer.allocate(1024); // 增大缓冲区大小

        try {
            int bytesRead = channel.read(buffer);
            if (bytesRead == -1) {
                // 客户端正常关闭
                System.out.println("客户端正常断开: " + channel.getRemoteAddress());
                closeChannel(key, channel);
            } else if (bytesRead > 0) {
                buffer.flip();
                byte[] bytes = new byte[buffer.remaining()];
                buffer.get(bytes);
                System.out.println("收到数据: " + new String(bytes));
            }
        } catch (ClosedChannelException e) {
            // 连接已被关闭
            closeChannel(key, channel);
        } catch (IOException e) {
            // 处理连接重置等异常
            System.err.println("客户端异常断开: " + e.getMessage());
            closeChannel(key, channel);
        }
    }

    private static void closeChannel(SelectionKey key, SocketChannel channel) {
        key.cancel();
        try {
            if (channel != null) {
                System.out.println("关闭客户端连接: " + channel.getRemoteAddress());
                channel.close();
            }
        } catch (IOException ex) {
            ex.printStackTrace();
        }
    }
}




